/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.mygameframework.util;

import java.awt.Point;

/**
 *
 * @author bill
 */
public class Vector2D {
    public double x,y;
    public Vector2D(){this(0.0,0.0);}
    public Vector2D(double x, double y) { this.x=x;this.y=y;}
    public void zero(){x=0.0; y=0.0;}
    public boolean isZero(){
        return lengthSq()<=0.0001;
//        return lenghtSq()<Double.MIN_VALUE;
    }
    /**
     * 未开方的勾股距里
     * @return
     */
    public double lengthSq(){
        return x*x+y*y;
    }
    /**
     * 该向量的长度(模长 ,执行开方)
     */
    public double length(){
        return Math.sqrt(lengthSq());
    }
    public double distanceSq(Vector2D v2) {
        double ySeparation = v2.y - y;
        double xSeparation = v2.x - x;
        return ySeparation * ySeparation + xSeparation * xSeparation;
    }
    //两向量之间  欧几里德 距离
    public double distance(Vector2D v2) {
        return Math.sqrt(distanceSq(v2));
    }
    //点乘 ,该操作不影响自身向量的x和y值
    public double dot(Vector2D v2){
        return this.x*v2.x+this.y*v2.y;
    }
    //反向量 ,该操作不影响自身向量的x和y值
    public Vector2D getReverse(){
        return new Vector2D(-x, -y);
    }

    public boolean insideRegion(Vector2D p,
                         Vector2D top_left,
                         Vector2D bot_rgt){
        return !(p.x<top_left.x | p.y<top_left.y
                | p.x>bot_rgt.x | p.y>bot_rgt.y);
    }
    public boolean notInsideRegion(Vector2D p,
                         Vector2D top_left,
                         Vector2D bot_rgt){
        return !insideRegion(p, top_left, bot_rgt);
    }
    //点p 是否在某区域内
    public boolean insideRegion(Vector2D p, int left, int top,
            int right, int bottom) {
        return !(p.x < top | p.y < left | p.x > bottom | p.y > right);
    }
    //单位化,该操作会影响当前this的x和y值
    public void normalize(){
        double vectorLength=this.length();
         //TODO 硬编码  0.0001
        if(vectorLength<=0.0001) vectorLength=1;
        x/=vectorLength;
        y/=vectorLength;
        if(x<=0.0001) x=0.0;
        if(y<=0.0001) y=0.0;
    }
    public static Vector2D pointToVector(Point p){
        return new Vector2D(p.x, p.y);
    }
    public static Point vectorToPoint(Vector2D v2){
        return new Point(Math.round((float)v2.x),Math.round((float)v2.y));
    }
    //返回垂直于该向量的向量 perpendicular vector2d 
    public Vector2D perp() {
        return new Vector2D(-y, x);
    }

    //--------------------------- Reflect ------------------------------------
// 给定一个单位化向量,
//  given a normalized vector this method reflects the vector it
//  is operating upon. (like the path of a ball bouncing off a wall)
//------------------------------------------------------------------------
    public void reflect(Vector2D norm) {
        Vector2D v= norm.getReverse().multiplication(2.0*this.dot(norm));
        add(v);
        //this += 2.0 * this.dot(norm) * norm.getReverse();
    }

    //  returns positive if v2 is clockwise of this vector,
//  minus if anticlockwise (Y axis pointing down, X axis to right)
    public int sign(Vector2D v2) {
        if (y * v2.x > x * v2.y) {
            return -1;//anticlockwise;//逆时针方向
        } else {
            return 1;//clockwise;//顺时针
        }
    }
    //  truncates a vector so that its length does not exceed max
    public void truncate(double max){
        if(length()>max){
            this.normalize();
            multiplication(max);//单位化向量 * max
        }
    }
    public static double vec2DDistanceSq(Vector2D v1, Vector2D v2) {
        double ySeparation = v2.y - v1.y;
        double xSeparation = v2.x - v1.x;
        return ySeparation * ySeparation + xSeparation * xSeparation;
    }

    public static double vec2DDistance(Vector2D v1, Vector2D v2) {
        return Math.sqrt(vec2DDistance(v1, v2));
    }

    public static double vec2DLengthSq(Vector2D v) {
        return (v.x * v.x + v.y * v.y);
    }

    public static double vec2DLength(Vector2D v) {
        return Math.sqrt(vec2DLengthSq(v));
    }
    //返回经单位化的向量v的副本
    public Vector2D vec2DNormalize(Vector2D v){
        Vector2D vClone=new Vector2D(v.x, v.y);
        vClone.normalize();
        return vClone;
    }



    /////////////////////////////////////////
    //向量相加 ,该操作会影响当前this的x和y值
    public Vector2D add(Vector2D v2){
        this.x+=v2.x;this.y+=v2.y;
        return this;
    }
    //向量相减,该操作会影响当前this的x和y值
    public Vector2D subtract(Vector2D v2){
        this.x-=v2.x;this.y-=v2.y;
        return this;
    }
    //向量与一系数相乘,该操作会影响当前this的x和y值
    public Vector2D multiplication(double d){
        this.x*=d;this.y*=d;
        return this;
    }
    //向量除以系数d,该操作会影响当前this的x和y值
    public Vector2D division(double d){
        this.x/=d;this.y/=d;
        return this;
    }



}
